export type itemStyleType = {
  [key: string]: string;
};

export type dataType = {
  name: string;
  value: number;
  itemStyle?: itemStyleType;
};

/**
 * @description:   colorFormatter function
 * @param {Array<string> | string | Map<any, string>} colorList   color list
 * @return {*}
 */
export function colorFormatter(colorList: Array<string> | string | Map<any, string>) {
  if (!colorList) return "#CCB18F";
  if (typeof colorList === "string") {
    return colorList;
  } else {
    return function (params) {
      if (colorList instanceof Array) {
        const i = params.dataIndex % colorList.length;
        return colorList[i];
      } else if (colorList instanceof Map) {
        return colorList.get(params.name);
      }
    };
  }
}

/**
 * @description:  获取配置信息 - 饼图
 * @param {any} ec                  echarts 实例
 * @param {Array} data              echarts 数据
 * @param {string} title            echarts 标题
 * @param {string} unit             echarts 单位
 * @param {CommonEcharts.CommonEchartsOption} ag   剩余参数，类型为 CommonEcharts.CommonEchartsOption
 * @return {CommonEcharts.CommonEchartsOption}     返回 echarts 配置信息
 */
export function useLabelLayoutPieChartFn(
  ec?: any,
  data?: Array<dataType>,
  title: string = "",
  unit: string = "",
  colorList: Array<string> | string | Map<any, string> = [],
  ag: CommonEcharts.CommonEchartsOption = {}
): CommonEcharts.CommonEchartsOption | null {
  if (!ec) return null;
  if (!data?.length) return null;
  const { getWidth = null } = ec;
  const labelLayout = function (params) {
    if (!getWidth) return null;
    const isLeft = params.labelRect.x < getWidth() / 2;
    const points = params.labelLinePoints;
    points[2][0] = isLeft ? params.labelRect.x : params.labelRect.x + params.labelRect.width;
    return { labelLinePoints: points };
  };
  const options: CommonEcharts.CommonEchartsOption = {
    tooltip: {
      trigger: "item",
      formatter: "{a} <br/>{b} : {c} ({d}%)"
    },
    grid: {
      left: 0,
      right: 0,
      top: 0,
      bottom: 0,
      containLabel: true
    },
    series: [
      {
        name: title,
        type: "pie",
        radius: [0, 40],
        center: ["50%", "50%"],
        label: {
          // alignTo: "edge",
          formatter: `{name|{b}}\n{num|{c}${unit}}{percent| ( {d}% )}`,
          minMargin: 2,
          edgeDistance: 10,
          lineHeight: 20,
          rich: {
            num: {
              fontSize: 14,
              color: "#222",
              lineHeight: 20,
              fontWeight: 600
            },
            percent: {
              fontSize: 10,
              color: "#333",
              lineHeight: 20
            }
          }
        },
        labelLine: {
          show: true,
          // length: 15,
          // length2: 0,
          maxSurfaceAngle: 85
        },
        labelLayout,
        data,
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: "rgba(0, 0, 0, 0.5)"
          }
        },
        itemStyle: {
          color: colorFormatter(colorList)
        }
      }
    ]
  };
  return { ...options, ...ag } as CommonEcharts.CommonEchartsOption;
}

/**
 * @description:   获取配置信息 - 环形图
 * @param {any} ec                  echarts 实例
 * @param {Array} data              echarts 数据
 * @param {string} title            echarts 标题
 * @param {string} unit             echarts 单位
 * @param {CommonEcharts.CommonEchartsOption} ag   剩余参数，类型为 CommonEcharts.CommonEchartsOption
 * @return {CommonEcharts.CommonEchartsOption}     返回 echarts 配置信息
 * @param {boolean} dark            是否开启暗黑模式 默认false
 */
export function useLabelLayoutRingGraphFn(
  ec?: any,
  data?: Array<dataType>,
  title: string = "",
  unit: string = "",
  colorList: Array<string> | string | Map<any, string> = [],
  ag: CommonEcharts.CommonEchartsOption = {},
  dark: boolean = false
): CommonEcharts.CommonEchartsOption | null {
  if (!ec) return null;
  if (!data?.length) return null;
  const { getWidth = null } = ec;
  const labelLayout = function (params) {
    if (!getWidth) return null;
    const isLeft = params.labelRect.x < getWidth() / 2;
    const points = params.labelLinePoints;
    points[2][0] = isLeft ? params.labelRect.x : params.labelRect.x + params.labelRect.width;
    return { labelLinePoints: points };
  };
  const options: CommonEcharts.CommonEchartsOption = {
    title: {
      text: title,
      textStyle: {
        color: dark ? "#fff" : "#555",
        fontSize: 16,
        fontWeight: 500,
        lineHeight: 18
      },
      left: "center",
      top: "center"
    },
    tooltip: {
      trigger: "item",
      formatter: function (params) {
        const { marker, name, value, percent } = params;
        const d = `${marker}${name}：  ${value}（${percent}%）`;
        return d;
      }
    },
    grid: {
      left: 0,
      right: 0,
      top: 0,
      bottom: 0,
      containLabel: true
    },
    series: [
      {
        name: title,
        type: "pie",
        radius: [32, 52],
        center: ["50%", "50%"],
        label: {
          // alignTo: "edge",
          formatter: `{name|{b}}\n{num|{c}${unit}}{percent| ( {d}% )}`,
          minMargin: 2,
          edgeDistance: "10%",
          lineHeight: 20,
          rich: {
            num: {
              fontSize: 14,
              color: dark ? "#eee" : "#333",
              lineHeight: 20,
              fontWeight: 600
            },
            percent: {
              fontSize: 10,
              color: dark ? "#eee" : "#555",
              lineHeight: 20
            }
          }
        },
        labelLine: {
          show: true,
          // length: 15,
          // length2: 0,
          maxSurfaceAngle: 85
        },
        labelLayout,
        data,
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: "rgba(0, 0, 0, 0.5)"
          }
        },
        itemStyle: {
          color: colorFormatter(colorList)
        }
      }
    ]
  };
  return { ...options, ...ag } as CommonEcharts.CommonEchartsOption;
}

/**
 * @description:   获取配置信息 - 柱状图
 * @param {any} ec                  echarts 实例
 * @param {Array} xAxisData         同 echarts xAxisData 配置
 * @param {Array} data              echarts 数据
 * @param {string} title            echarts 标题
 * @param {string} unit             echarts 单位
 * @param {boolean} legendHidden    是否隐藏legend
 * @param {string} labelPosition    label 位置 默认为 inside
 * @param {CommonEcharts.CommonEchartsOption} ag   剩余参数，类型为 CommonEcharts.CommonEchartsOption
 * @return {CommonEcharts.CommonEchartsOption}     返回 echarts 配置信息
 */
export function useLabelLayoutBarChartFn(
  ec?: any,
  xAxisData?: Array<string>,
  data?: Array<number>,
  title?: string,
  unit?: string,
  colorList?: Array<string> | string | Map<any, string>,
  legendHidden?: boolean,
  labelPosition?: string,
  ag?: CommonEcharts.CommonEchartsOption
): CommonEcharts.CommonEchartsOption | null {
  if (!ec) return null;
  if (!xAxisData?.length) return null;
  if (!data?.length) return null;
  const label = {
    show: true,
    position: labelPosition ? labelPosition : "inside"
  };
  const emphasis = {
    focus: "series"
  };
  const legend = {
    show: !legendHidden
  };
  const tooltip: any = {
    trigger: "axis",
    axisPointer: {
      type: "shadow"
    },
    formatter: function (params) {
      const { marker, name, value } = params[0];
      const d = `${marker}${name}：  ${value}`;
      return d;
    }
  };
  const commonOptions: CommonEcharts.CommonEchartsOption = {
    title: {
      show: !!unit,
      subtext: `单位 / ${unit}`,
      left: -5,
      top: -6
    },
    legend,
    tooltip,
    grid: {
      left: 0,
      right: 0,
      top: 30,
      bottom: 0,
      containLabel: true
    },
    xAxis: [
      {
        type: "category",
        data: xAxisData
      }
    ],
    yAxis: [
      {
        type: "value"
      }
    ]
  };
  const series: Array<any> = [
    {
      name: title,
      type: "bar",
      label,
      emphasis,
      data: data,
      itemStyle: {
        color: colorFormatter(colorList)
      }
    }
  ];
  const options: CommonEcharts.CommonEchartsOption = { ...commonOptions, series };
  return { ...options, ...ag } as CommonEcharts.CommonEchartsOption;
}

export function useLabelLayoutBarChartFn_new(
  ec?: any,
  xAxisData?: Array<string>,
  data?: Array<number>,
  title?: string,
  unit?: string,
  colorList?: Array<string> | string | Map<any, string>,
  legendHidden?: boolean,
  labelPosition?: string,
  ag?: CommonEcharts.CommonEchartsOption
): CommonEcharts.CommonEchartsOption | null {
  if (!ec) return null;
  if (!xAxisData?.length) return null;
  if (!data?.length) return null;
  const label = {
    show: true,
    position: labelPosition ? labelPosition : "inside"
  };
  const emphasis = {
    focus: "series"
  };
  const legend = {
    show: !legendHidden
  };
  const tooltip: any = {
    trigger: "axis",
    axisPointer: {
      type: "shadow"
    },
    formatter: function (params) {
      const { marker, name, value } = params[0];
      const d = `${marker}${name}：  ${value}`;
      return d;
    }
  };
  const commonOptions: CommonEcharts.CommonEchartsOption = {
    title: {
      show: !!unit,
      subtext: `${unit}`,
      left: -5,
      top: -6
    },
    legend,
    tooltip,
    grid: {
      left: 0,
      right: 0,
      top: 45,
      bottom: 0,
      containLabel: true
    },
    xAxis: [
      {
        type: "category",
        data: xAxisData
      }
    ],
    yAxis: [
      {
        type: "value"
      }
    ]
  };
  const series: Array<any> = [
    {
      name: title,
      type: "bar",
      label,
      emphasis,
      data: data,
      itemStyle: {
        color: colorFormatter(colorList)
      }
    }
  ];
  const options: CommonEcharts.CommonEchartsOption = { ...commonOptions, series };
  return { ...options, ...ag } as CommonEcharts.CommonEchartsOption;
}
// 复制一份去修改开始

export function useGetBarChartsAgOptions_new(
  xAxisData?: Array<string>,
  data?: Array<number>,
  flag?: boolean,
  unit?: string,
  colorList?: Array<string> | string | Map<any, string>,
  barWidth?: number,
  backgroundColor?: string
): CommonEcharts.CommonEchartsOption | null {
  const legend = { show: false };
  const title = {
    show: !!unit,
    subtext: `${unit}`,
    left: -5,
    top: -6
  };
  const grid = {
    left: 0,
    right: 0, //32
    top: 30, //20
    bottom: 0,
    containLabel: true
  };
  const axis_1 = { show: !flag };
  const axis_2 = [
    {
      type: "category",
      data: xAxisData,
      axisLine: { show: !flag },
      axisTick: { show: !flag }
    }
  ];
  const xAxis = flag ? axis_1 : axis_2;
  const yAxis = flag ? axis_2 : axis_1;
  const label = {
    show: true,
    position: flag ? "right" : "top"
  };
  const emphasis = {
    focus: "series"
  };
  const series: Array<any> = [
    {
      name: title,
      type: "bar",
      label,
      emphasis,
      data: data,
      itemStyle: {
        color: colorList ? colorFormatter(colorList) : undefined
      }
    }
  ];
  barWidth && (series[0].barWidth = barWidth);
  const ag: CommonEcharts.CommonEchartsOption = { legend, title, grid, xAxis, yAxis, series };
  backgroundColor && (ag["backgroundColor"] = backgroundColor);
  return ag;
}
// 复制一份修改 结束

/**
 * @description:   获取剩余参数 - 柱状图 （legend, title, grid, xAxis, yAxis, series）
 * @param {Array} xAxisData    同 echarts xAxisData 配置
 * @param {Array} data         echarts 数据
 * @param {Array} colorList    echarts 柱体颜色list
 * @param {boolean} flag       是否横向，默认为 false（纵向）
 * @param {string} unit        单位
 * @return {CommonEcharts.CommonEchartsOption}
 */
export function useGetBarChartsAgOptions(
  xAxisData?: Array<string>,
  data?: Array<number>,
  flag?: boolean,
  unit?: string,
  colorList?: Array<string> | string | Map<any, string>,
  barWidth?: number,
  backgroundColor?: string
): CommonEcharts.CommonEchartsOption | null {
  const legend = { show: false };
  const title = {
    show: !!unit,
    subtext: `单位 / ${unit}`,
    left: -5,
    top: -6
  };
  const grid = {
    left: 0,
    right: 32, //32
    top: 20, //20
    bottom: 0,
    containLabel: true
  };
  const axis_1 = { show: !flag };
  const axis_2 = [
    {
      type: "category",
      data: xAxisData,
      axisLine: { show: !flag },
      axisTick: { show: !flag }
    }
  ];
  const xAxis = flag ? axis_1 : axis_2;
  const yAxis = flag ? axis_2 : axis_1;
  const label = {
    show: true,
    position: flag ? "right" : "top",
    formatter: unit ? `{c}${unit}` : `{c}`
  };
  const emphasis = {
    focus: "series"
  };
  const series: Array<any> = [
    {
      name: title,
      type: "bar",
      label,
      emphasis,
      data: data,
      itemStyle: {
        color: colorList ? colorFormatter(colorList) : undefined
      }
    }
  ];
  barWidth && (series[0].barWidth = barWidth);
  const ag: CommonEcharts.CommonEchartsOption = { legend, title, grid, xAxis, yAxis, series };
  backgroundColor && (ag["backgroundColor"] = backgroundColor);
  return ag;
}

/**
 * @description:     获取剩余参数 - 环形图（title, graphic）
 * @param {number} total    总计
 * @param {boolean} dark    是否开启暗黑模式 默认false
 * @return {CommonEcharts.CommonEchartsOption}
 */
export function useGetRingGraphAgOptions(total = 0, dark: boolean = false): CommonEcharts.CommonEchartsOption | null {
  const graphic = [
    {
      type: "text",
      left: "center",
      top: "center",
      style: {
        text: `${total ?? "未知"}\n总计`,
        textAlign: "center",
        fill: dark ? "#fff" : "#333",
        fontSize: 18,
        lineHeight: 20
      }
    }
  ];
  const title = {};
  const ag: CommonEcharts.CommonEchartsOption = { title, graphic };
  dark && (ag["backgroundColor"] = "transparent");
  return ag;
}

/**
 * @description:  判断 echarts options 数据是否为空
 * @param {CommonEcharts} options
 * @param {boolean} flag  是否根据 series data 判断是否渲染echarts
 * @return {boolean}
 */
export function useIsEchartsOptionNotEmpty(options: CommonEcharts.CommonEchartsOption | null, flag: boolean = true): boolean {
  if (!options) return false;
  const { series = [] } = options;
  if (!series || !series?.length || !series?.some(item => item)) return false;
  // 判断 data 是否不为空
  function isDataNotEmpty(data: Array<any>): boolean {
    if (data?.some(item => typeof item === "number")) {
      return true;
    } else if (data?.some(item => Object.prototype.toString.call(item) === "[object Object]")) {
      return flag ? data?.some(item => item && (item.value || item.value === 0)) : true;
    } else {
      return flag ? false : true;
    }
  }
  return series.reduce((pre, cur) => {
    if (pre) return pre;
    switch (cur.type) {
      case "line":
        pre = isDataNotEmpty(cur.data);
        break;
      case "bar":
        pre = isDataNotEmpty(cur.data);
        break;
      case "pie":
        pre = isDataNotEmpty(cur.data);
        break;
      case "funnel":
        pre = isDataNotEmpty(cur.data);
        break;
      case "gauge":
        pre = isDataNotEmpty(cur.data);
        break;
      default:
        pre = true;
        break;
    }
    return pre;
  }, false);
}
